iT邦幫忙

2023 iThome 鐵人賽

DAY 19
0

開心開心,我們的各種環境越來越完善了,接下來就是新的挑戰了,大家看我們用 IP 連線我們的 PVE 服務一直被問「你的連線不是私人連線」想必也看得很煩躁了吧?究竟是什麼原因呢?我們來看看吧!

Your connection is not private page

為什麼會有「你的連線不是私人連線的問題」?

在我們往下聊之前,先跟大家聊聊 HTTP 協定,我們網址列前面的 HTTP 到底是什麼?為什麼有時候會顯示 HTTPS 呢?

關於 HTTP 協定

HTTP 的全名叫 Hyper Text Transfer Protocol,中文叫超文本傳輸協議,這個協議也被譽為是全球資訊網的基礎。今天當我們期望瀏覽一個網站的資訊或者在網路世界做互動時,我們都是透過 HTTP 協定來傳輸資料的。但是 HTTP 其實有個小問題,也就是當初在考量 HTTP 傳輸時,只期望資訊能正確傳遞並規定該如何互動,卻忘記考量了安全性的部分,也就是其並不在乎資料是否被竊取或者被竄改的問題,換句話說,當連線是用 HTTP 協定時,我們的資料是以明文的方式傳輸的,這也就是為什麼我們在網路上看到的各種資料竊取的案例,都是透過竊取 HTTP 的資料來進行的,因為其無需破解任何加密的資料,就能直接看到我們的資料。那也正因為 HTTP 的所有資訊傳遞皆為明文,因此現在當我們連線到 HTTP 的網站時,瀏覽器會預設此網站的操作皆是不安全的,原因在於假如我們在這樣的連線中有例如帳號密碼操作的行為,那等於所有東西都直接裸露給網路世界的人看了,因此瀏覽器會預設這樣的網站是不安全的,並且會提醒我們。

那你可能會問,「哇!那我們一直都用 HTTP 訪問我們的 PVE 不知道多久了!怎麼辦!帳密都給別人了啦!」,嘿嘿,不用緊張,忘記我們是怎麼跟內網的 PVE 互動了嗎?為什麼之前一直沒有管是不是 HTTP 協定的傳輸呢?因為我們的 VPN 已經將所有互動操作進行封裝加密了,因此跟內部服務互動時沒有 HTTP 是不用過度緊張的。

但是總不會我們用 VPN 跟全世界的所有網站做互動保護吧?首先先不說這可不可行,也太勞民傷財了,因此 HTTP 是透過明文傳輸資訊的問題勢必會需要被解決,因此就有了 HTTPS 的出現。

關於 HTTPS 協定

HTTPS 的全名就叫做 Hyper Text Transfer Protocol Secure,誒誒誒,別罵我,這是真的,就是「安全的 HTTP 協定」的意思啦!那 HTTPS 的 S 到底是多了什麼呢?原理又是什麼?

HTTPS 是使用了通訊加密協定對通訊進行加密的行為,而這個通訊協定被稱為 TLS(Transport Layer Security),但之前稱為 SSL(Secure Sockets Layer,安全通訊端層),他們兩個都是加密協定,主要用於在網路上傳輸資料時確保資料的安全性。TLS 是 SSL 的後續版本,現在已經是主流的加密協定。而通訊協定使用之前提過的非對稱是加密來保護通訊,也就是會有一個私鑰一個公鑰。而 HTTPS 的 S 就是透過這樣的加密協定來保護我們的資料,讓我們的資料不會以明文的方式在網路上傳輸,因此我們的資料就不會被竊取了。

那一般來說

  1. 私鑰:此金鑰由網站擁有者控制,並且如讀者所推測的那樣,它是私有的。此金鑰位於 Web 伺服器上,用於解密透過公開金鑰加密的資訊。
  2. 公鑰:所有想要以安全方式與伺服器互動的人都可以使用此金鑰。用公開金鑰加密的資訊只能用私密金鑰解密。

因此概念上來說就是,今天我們要跟這個伺服器互動的時候,我們先拿它的公鑰把我們的資料加密,然後再傳給伺服器,伺服器再用它的私鑰解密,這樣就能保護我們的資料了。讚讚,很簡單吧!

如何讓 HTTP 升等為 HTTPS 呢?

要讓 HTTP 順利進化成 HTTPS,我們需要做幾件事情:

  1. 首先,我們要先取得 TLS/SSL 證書
  2. 然後,我們要將伺服器上安裝和設定 TLS/SSL 證書
  3. 最後,我們要將伺服器上的 HTTP 服務轉換成 HTTPS 服務

那我們就來一個一個看吧!

取得 TLS/SSL 證書

SSL 證書是一種數位證書,用於確認網站的身份和提供公鑰以建立安全的連線。當用戶訪問一個使用 SSL 的網站時,網站會提供其證書以證明其合法性。

取得 SSL 證書的方法:

  • 購買於認證機構(CA,Certificate Authority )。
  • 自己建立(自簽名證書),但這種證書不會被大多數瀏覽器信任。

那一般來說要找認證機構購買證書呢是最穩定的做法,因為身為第三方發證機構,往往在穩定性上還有信任度上都會比較好,但是這樣的證書往往都是要付費的,而且畢竟只是一個小小的家用伺服器,我們也不需要那麼高的安全性,我們就試試看自己有什麼免費的解決方案吧!

概念釐清與補充

首先在準備往下討論之前,我們稍微重新整理一下所有概念。

首先在憑證的世界中,主要會有幾個主要的角色互相互動,分別是:

  1. CA - Certificate Authority,憑證授權中心,負責發放憑證的單位,也就是我們剛剛提到的認證機構。那這個機構可以是第三方維護的公信力發證單位,又或者我們可以自行為自己建立一個 CA 來發證。
  2. Certificate - 憑證,是由 CA 簽署的憑證,用來證明我們的身份,也就是我們剛剛提到的 SSL 證書。那一般來說當我們的伺服器有正確簽署的證書之後,瀏覽器可以透過憑證來驗證我們的身份,並且確認我們的身份是可信任的。另外今天瀏覽器與伺服器互動時,也可以藉由憑證中所提供的公鑰對資訊進行加密。
  3. Browser - 瀏覽器,會利用憑證中的公鑰來加密資訊,並且驗證憑證的合法性。
  4. Server - 伺服器,會放置 CA 所簽署的憑證,並放置在可以被取得的路徑中,讓瀏覽器可以取得。
  5. Domain - 域名

我們先從幾個東西來說明,首先當我們今天會需要為一個服務取得憑證時,我們會需要一個 CA 來簽署憑證,而這個 CA 可以是第三方的 CA,也可以是我們自己建立的 CA,而這個 CA 會為我們的憑證簽署,而這個憑證就是我們的 SSL 證書,而這個憑證會放置在我們的伺服器上,讓瀏覽器可以取得,而瀏覽器會透過憑證中的公鑰來加密資訊,並且驗證憑證的合法性。但是為什麼這邊突然冒出一個域名呢?主要是因為今天憑證的概念其實是“證明這個服務是你的 & 安全的”,也就是說他不是純粹的在驗證 Key 而已,他跟使用者說明目前的服務是安全的原因是因為這個服務是一個安全的服務提供商所提供的,也就是說他正在證明「我正擁有這個服務」這個概念,而為了實現這個概念的驗證,他們是利用證明我是 Domain 的擁有者來進行的,也就是說他們會要求我們提供一個 Domain 來進行驗證,而這個 Domain 會被放置在憑證中,讓瀏覽器可以驗證。

所以你可能會問,「用 IP 連線就必定只能是 HTTP 而不會是 HTTPS 嗎?取得憑證一定要有 Domain 才能簽署嗎?」針對這個問題:

  1. IP 連線是否可以是 HTTPS,可以的,當我們今天在瀏覽器中輸入 https://[IP地址] 時,它會嘗試建立一個 HTTPS 連線。但是,大多數的 SSL/TLS 憑證都是基於域名而不是 IP 地址簽發的,所以當我們使用 IP 地址訪問 HTTPS 網站時,瀏覽器通常會顯示一個安全警告,因為憑證的域名和您輸入的 IP 地址不匹配。
  2. 而大部分的情況下要取得憑證必定要有 domain 方能簽署,因為公認的證書授權中心 (CA) 通常基於域名簽發憑證。這意味著我們需要擁有一個域名,並且能夠證明我們對該域名的控制權,以便從這些 CA 處獲得憑證。但是,也有所謂的 "IP 地址憑證",這些憑證是基於 IP 地址而不是域名簽發的。然而,這些憑證不是那麼常見,且可能需要特定的應用場景或特殊的需求。

因此回到今天的目標,今天我們的目標是讓 PVE 可以擁有不會顯示「你的連線不是私人連線」的連線方式,所以其實針對這個問題我們有幾個解決方法:

  1. 是否有免費的 CA 可以為我們簽署憑證可以直接使用?
  2. 我們是否可以自己建立一個 CA 來為我們自己發放憑證呢?

讓我們往下看吧!

為 PVE 準備憑證

前面有提過了,我們其實要達成這個目標有兩種方法,一種是從別人身上取得憑證,一種是自己建立 CA 來簽署憑證,那我們就來看看這兩種方法吧!

PVE 的憑證準備

當你今天在 Google 輸入 PVE Certificate 這個 Keyword 時,會發現官方文件有一個關於 PVE 取得憑證的說明 PVE Certificate Managment / PVE 的憑證管理,那這個文件有說明到 PVE 其實是由 pveproxy 做服務提供的,其中如果要對 pveproxy 進行憑證簽署,其實有以下幾個選項:

  1. 預設下,在 /etc/pve/nods/NODENAME/pve-ssl.pem 中的節點有特定的預設憑證了。這些憑證是由 PVE 的叢集 CA 所簽署,因此當然瀏覽器跟 OS 是預設不會自動信任此憑證的,但可以藉由添加此憑證到瀏覽器的信任憑證中,來達到信任的效果。
  2. 使用外部已經取得的憑證,這個方法就是我們之前提到的,如果你有購買憑證的話,可以直接使用這個方法。
  3. 使用 ACME(Let's Encrypt)取得可自動續訂的可信任憑證,而這個目前被整合在 PVE API 跟 Web GUI 中。

而對於 2 / 3 兩個選項,都是預設使用 /etc/pve/local/pveproxy-ssl.pem/etc/pve/local/pveproxy-ssl.key,預設沒有密碼)。

那這邊冒出了一個新的名詞,什麼是 ACME?ACME (Automatic Certificate Management Environment) 是一種協定,用於自動化從支援的證書授權中心(如 Let's Encrypt)取得、驗證、撤銷和續期 SSL/TLS 證書的過程。ACME 的主要目的是使整個證書管理過程更加自動化,從而減少人工干預和錯誤。當使用 ACME 驗證時,您的伺服器或應用程式會自動與證書授權中心通訊,證明其對指定域名的控制權,並取得或續期證書。也因此當你看 Let's Encrypt 的官方文件時,會發現說明裡面他們大量使用「挑戰」跟「考驗」來說明他們的操作,這其實就是因為其概念在於持續跟 Let's Encrypt “證明” 我擁有這個網域的控制權,因此他們會不斷的發出挑戰,而我們要不斷的通過這些挑戰,才能取得證書。

https://letsencrypt.org/zh-tw/docs/challenge-types/

那既然我們要使用 ACME 來取得證書,那我們就來看看 PVE 的官方文件是怎麼說的吧!

首先我們先到 Datacenter > 選擇 ACME 可以看到以下畫面,其中 ACME Account 主要是用來用來作為一個用來驗證的帳號,而 ACME 的 Challenge Plugins 則是用來為我們向 Let's Encrypt 發出挑戰的設定,用來證明 Domain 是我們的一個步驟,而 PVE 所支援的挑戰方式很多,讓我們一個一個來。

PVE ACME Page

接下來我們還需要為我們的 PVE 準備 domain 跟取得第一次的證書,這邊我們就依照下方截圖來逐步操作即可!

PVE Node Certificates Setting and Get CA

這邊有幾個非常重要的部分要注意,

  1. 首先我們要確認我們 PVE 的 80 Port 沒有被任何已知服務佔用,因為 ACME 的預設 HTTP-01 考驗 會直接使用 80 Port 來針對 Domain 進行挑戰,因此如果 80 Port 被佔用的話,就會導致挑戰失敗。
  2. 我們的 PVE 的 80 Port 也必須被暴露在外網,也因此我們需要確認我們的 PVE 有被正確的 Port Forwarding 到外網。
  3. Domain 的 IP 設定等等都要正確,不然會導致挑戰失敗。

基本上到這邊我們就完成最簡單的 ACME 對 PVE 的憑證簽署了!這時候在用 domain 針對 PVE 進行連線的話,就會發現瀏覽器已經不會再提醒我們不安全的問題了!

小結

到這邊我們就算是完成幫我們的 PVE 進行簽署了,但可以發現首先

  1. 80 port 這麼常用且重要的 port 就這樣被佔用了,似乎有些可惜
  2. 如果今天很不幸的 HTTP-01 的簽署驗證沒過,是否有其他方法做到?
  3. 今天要幫其他服務簽署憑證,可沒有 PVE 這麼方便的系統,要怎麼簽署?

讓我們明天再來聊聊吧!


上一篇
Day-17 - 深入瞭解 VPN 核心,從加密技術看 VPN 安全 - 03
下一篇
Day-19 - 準備自己的 HTTPS 網站 - Day-19 - 準備自己的 HTTPS 網站 - DNS Challenge / 自建 ACME Client
系列文
誒,想不到有一天搞懂網路是因為宿舍學長逼我的QQ!30天的宿舍網路架設31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言